package cn.kzgg.ymcc.service.impl;

import cn.kzgg.ymcc.Exception.GlobleException;
import cn.kzgg.ymcc.constants.CommonConstants;
import cn.kzgg.ymcc.domain.MessageSms;
import cn.kzgg.ymcc.domain.RemoveBlack;
import cn.kzgg.ymcc.dto.RedisRegisterDto;
import cn.kzgg.ymcc.dto.RegisterDto;
import cn.kzgg.ymcc.mapper.MessageSmsMapper;
import cn.kzgg.ymcc.mapper.RemoveBlackMapper;
import cn.kzgg.ymcc.service.IMessageSmsService;
import cn.kzgg.ymcc.service.IRegisterService;
import cn.kzgg.ymcc.service.IRemoveBlackService;
import cn.kzgg.ymcc.util.AssertUtil;
import cn.kzgg.ymcc.util.StrUtils;
import cn.kzgg.ymcc.util.VerifyCodeUtils;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RegisterServiceImpl  implements IRegisterService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IMessageSmsService messageSmsService;

    @Autowired
    private RemoveBlackMapper removeBlackMapper;
    @Autowired
    private IRemoveBlackService removeBlackService;

    /**
     * 图片验证码
     *
     * @param key
     */
    @Override
    public String imageCode(String key) {
        //1.判断key不为空
        if (!StringUtils.hasLength(key)) {
            throw new GlobleException("key不能为空");
        }
        //2.使用UUID生成一个图片验证码的值,每次都是新生的，如果前面有的话直接覆盖
        String code = StrUtils.getComplexRandomString(4);
        //3.把验证码的值存储到Redis,以前台传入的key作为key
        redisTemplate.opsForValue().set(
                key,//前端传回来的UUID
                code,//生成的图片验证码
                5,
                TimeUnit.MINUTES);
        //4.把验证码的值合并到图片
        //5.把图片使用Base64编码
        //6.返回base64编码的字符串
        return VerifyCodeUtils.verifyCode(100, 40, code);

    }

    /**
     * 短信验证码
     *
     * @param mobile
     */
    @Override
    public void sendSmsCode(String mobile,RegisterDto registerDto) {
        //一、检验
        //1.空校验
        if (StringUtils.isEmpty(mobile)) {
            throw new GlobleException("参数不能为空");
        }

        RemoveBlack removeBlack =selectRemoveBlackByPhone(registerDto.getMobile());
        AssertUtil.isNull(removeBlack,"你被拉黑了大兄弟");
        //2.格式校验
        AssertUtil.isPhone(mobile, "号码格式不合法");

        //二、验证逻辑
        //1.校验手机是否发送过验证码
        //验证码使用组合方式拼接key
        String key = String.format(CommonConstants.REGISTER_MOBILE_PROFIX, mobile);
        Object o = redisTemplate.opsForValue().get(key);
        Date now = new Date();
        //2.从redis拿到了，判断是否超过重发时间
        String code=null;
        if (o != null) {
            RedisRegisterDto redisRegisterDto = (RedisRegisterDto) o;
            //2.1没有超过使劲骂
            if ((now.getTime() - redisRegisterDto.getTime()) / 1000 < 60) {
                throw new GlobleException("我！@！你#！@#！￥%&￥……￥@#@");
            }
            //2.2过了重发时间就使用还没过期的验证码
            code = redisRegisterDto.getCode();
        }else{

            //3.没拿到，说明是第一次获取或者验证码已失效
            //3.1生成验证码
            code = StrUtils.getComplexRandomString(6);
            //3.2存储验证码
            //设置过期时间
            //String codeValue = code + ":" + System.currentTimeMillis();
            RedisRegisterDto redisRegisterDto = new RedisRegisterDto(code,now.getTime());
            redisTemplate.opsForValue().set(key,redisRegisterDto,2,TimeUnit.MINUTES);
            //3.3发送验证码
            String content = String.format("您的验证码是：" + code + ",请在十分钟内使用", code);
            String title="短信验证码";
            log.info(content);
            //3.4存储发送信息到数据库
            saveMsgSms(content,title,now);
        }



    }

    /**
     * 拉黑
     * @param mobile
     * @return
     */
    private RemoveBlack selectRemoveBlackByPhone(String mobile) {
        Wrapper<RemoveBlack> tWrapper = new EntityWrapper();
        tWrapper.eq("phone",mobile);  // where phone = 123123
        return removeBlackService.selectOne(tWrapper);
    }

    private void saveMsgSms(String content,String title,Date now) {
        MessageSms msg = new MessageSms();
        msg.setContent(content);
        msg.setTitle(title);
        msg.setSendTime(now);
        //获取请求体request保存ip地址
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        msg.setIp(request.getRemoteAddr());
        messageSmsService.insert(msg);

    }
}
